home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
apps
/
175
/
applic
/
yaps_t.s
< prev
next >
Wrap
Text File
|
1987-09-15
|
14KB
|
341 lines
ilabel TOS\TOS.L
;
; Program Equates
gpip = 0
len = 4
head = 8
tail = 12
gemdos = 1
bios = 13
xbios = 14
timeo = 30
keep = $31
porta = 14
portb = 15
trap13 = $B4
timerC = $114
savptr = $4A2
hz_200 = $4BA
MFP = $FFFFFA01
PSG = $FFFF8800
;
;Start of program for YAPS - timer C version
;
text
yaps: bra ypstrm ;Branch to temporary segment of program
check: dc.b 'YAPS_T.PRG'
;
; New Trap #13 Handler to intercept Printer Out and Status calls
;
newtrp: move.l savptr,A1 ;Save registers, sr, and return address
move.w (sp)+,D0 ; keeping a copy of sr to test for SUPER
move.w D0,-(A1) ; vs. User mode
move.l (sp)+,-(A1)
movem.l D3-D7/A3-A7,-(A1)
move.l A1,savptr ;Update save area pointer
btst #13,D0 ;Get correct stack pointer
bne newt10
move.l usp,sp
newt10: move.w (sp),D0 ;Get call number
cmp.w #3,D0 ;Check for "Conout"
bne newt30
tst.w 2(sp) ;If "Conout" then are we dealing with PRN: ?
bne newt50
move.w 4(sp),D1 ;Get character to print and do it!
bsr printo ;jump to print character
newt20: move.l savptr,A1 ;Restore registers, sr, and return address
movem.l (A1)+,D3-D7/A3-A7
move.l (A1)+,-(sp)
move.w (A1)+,-(sp)
move.l A1,savptr
rte
newt30: cmp.w #8,D0 ;Check for "Constat"
bne newt50
tst.w 2(sp) ;If "Constat" then are we dealing with PRN: ?
bne newt50
move.w sr,-(sp) ;Stop Timer C while testing printer buffer
ori.w #$0700,sr
moveq #-1,D0
bsr getptr ;Check to see if there is room in the
move.l tail(A0),D2 ; Printer Spooler. If so, the printer
bsr wrap ; must not be busy.
cmp.l head(A0),D2
bne newt40
moveq #0,D0
newt40: move.w (sp)+,sr ;Restart Timer C
bra newt20
newt50: move.l savptr,A1 ;Restore registers, sr, and return address
movem.l (A1)+,D3-D7/A3-A7
move.l (A1)+,-(sp)
move.w (A1)+,-(sp)
move.l A1,savptr
move.l trpsve,A0 ;Not a Printer call - then just continue
jmp (A0) ; on...
;
; Actual Timer C interrupt routine
; plus Printer Spooler out routine
;
timer: movem.l D0-D2/A0-A2,-(sp)
lea MFP,A1 ;save registers and load pointers
btst #0,gpip(A1) ;Check if printer BUSY
bne time10
bsr getptr ;Is there anything in buffer to print..
move.l head(A0),D2
cmp.l tail(A0),D2
beq time10
bsr wrap ;Set up pointers to retrieve character
move.l (A0),A2 ; to print.
move.b 0(A2,D2.l),D1
bsr notbus ;Branch to specialized printing routine
move.l D2,head(A0)
time10: movem.l (sp)+,D0-D2/A0-A2
timret: jmp $FFFFFFFF ;Chain to the Timer C Handler
;
; subroutine to send character to printer buffer OR printer
;
printo: bsr getptr ;Set up pointers
move.l head(A0),D2 ;If buffer already contains charcters
cmp.l tail(A0),D2 ; even if printer is now ready, store
bne inbuff ; any new characters in the buffer!
loop: btst #0,(A1) ;If printer is BUSY, store characters
bne inbuff ; in buffer.
notbus: move sr,-(sp) ;This is the specialized routine to output
ori #$0700,sr ; characters to a parallel printer. It has
movem.l D2-D5,-(sp) ; been optimized to pulse the strobe for
lea PSG,A2 ; 2 microseconds, which is the limit of the
moveq #portb,D2 ; sound chip!
asl.l #8,D2 ;Set up D2 to contain the character to print
add.b D1,D2 ; and the sound register to set up.
moveq #portb,D5 ;Set up D5 to send a null character to print
asl.l #8,D5 ; and the sound register to set up.
moveq #0,D0
move.b #7,(A2) ;Select the correct sound registers
move.b (A2),D0
or.b #$80,D0
move.b #7,(A2)
move.b D0,2(A2)
moveq #porta,D3 ;Set up D3 to pulse the strobe high
asl.l #8,D3
moveq #0,D4 ;Set up D4 to pulse the strobe low
move.b #porta,(A2)
move.b (A2),D4 ;Get the current configuration of Port A
and.b #$DF,D4 ;Finish setting up the contents of D3 to
move.b D4,D3 ; pulse the strobe
or.b #$20,D4
movep.w D2,0(A2) ;These next 4 statements actually write
movep.w D3,0(A2) ; the data to the Printer and pulse the
move.b D4,2(A2) ; strobe
movep.w D5,0(A2)
moveq #-1,D0 ;Return -1 as success
movem.l (sp)+,D2-D5
move (sp)+,sr
rts
inbuff: move.l tail(A0),D2 ;First check to see if there is any more
bsr wrap ; room in the printer buffer to store
cmp.l head(A0),D2 ; more characters
beq inb100
inb010: move.l (A0),A1 ;If there is room, store the character and
move.b D1,0(A1,D2.l) ; return -1 as success
move.l D2,tail(A0)
moveq #-1,D0
rts
inb100: move.l hz_200,D0 ;No room, then wait up to 30 seconds for the
add.l #timeo*200,D0 ; printer buffer to be cleared by the
wait: cmp.l head(A0),D2 ; Timer C interrupt
bne inb010
cmp.l hz_200,D0
bhi wait
moveq #0,D0 ;No luck, printer down - return 0
rts
;
;Routine to setup pointers
;
getptr: lea rec_io,A0
lea MFP,A1
rts
;
;Routine to wrap pointers around buffer
;
wrap: addq.l #1,D2
cmp.l len(A0),D2
bcs nowrap
moveq #0,D2
nowrap rts
;
; Data Segment - nonvolatile
;
rec_io: dc.l ypstrm
length: dc.l 0
dc.l 0
dc.l 0
;
; BSS Segment - nonvolatile
;
trpsve: ds.l 1
;
; Temporary Program Start
;
ypstrm: PRINTLINE tline ;Show title of program
bsr go_sup ;Enter SUPER mode and test to see if the
sub.l A2,A2 ; Printer Spooler has already been installed
move.l trap13(A2),A0
sub.l #10,A0 ;Check for title of program in the 10 bytes
lea check,A1 ; preceeding the start of the TRAP #13 handler
moveq #7,D1
yps000: cmpm.b (A1)+,(A0)+
bne yps040
dbra D1,yps000
bsr go_use ;return to use mode
PRINTLINE error5 ; ask if user wishes to clear buffer,
yps010: CONIN_WE ; then end program
and.b #$5F,D0
cmpi.b #'Y',D0
bne yps020
CONOUT D0
bsr go_sup ;To clear buffer, must first enter SUPER
move.w sr,-(sp) ; mode to stop all interrupts, including
ori.w #$0700,sr ; Timer C. Then clear the "head" and
sub.l A1,A1 ; "tail" values of pointer to buffer.
move.l trap13(A1),A0 ;Set up pointer to "head/tail"
add.l #length-newtrp+4,A0
clr.l (A0)
clr.l 4(A0)
move.w (sp)+,sr ;When done, start interrupts, get out of
bsr go_use ; SUPER mode, and leave.
TERM
yps020: cmpi.b #'N',D0
beq yps030
CONOUT #7
bra yps010
yps030: CONOUT D0
TERM
yps040: bsr go_use ;Restore to user mode
move.l 4(sp),A0 ;Calculate size of program...
move.l 4(A0),D7 ;D7 will contain the end of the available TPA
sub.l A0,D7 ; minus the basepage address
move.l #$100,D6 ;Size of base page
add.l 12(A0),D6 ;add TEXT length
add.l 20(A0),D6 ;add DATA length
add.l 28(A0),D6 ;add BSS length
GETDTA ;ASK THE OPERATING SYSTEM FOR OUR FILE NAME
move.l D0,A5 ;save address of current DTA
move.l #buflen,A4 ;Set up pointer to size of buffer indicator
SFIRST attrib,fname
tst D0 ;Test for file found
beq yap000
GETDIR #0,drvbuf ;If not, reset current drive to AUTO folder
CHDIR autobf ; and look again.
SFIRST attrib,fname
move.l D0,D4
CHDIR drvbuf
tst D4
beq yap000
PRINTLINE error1
bra yap060 ;NOW CHECK FILENAME FOR SIZE OF PRINTER BUFFER
yap000: moveq #34,D0 ;Set up index into DTA for filename
moveq #3,D1 ;Set up counter
moveq #0,D3
moveq #0,D5 ;This register will act as a flag for deleting
yap010: moveq #0,D2 ; preceeding zero's
move.b (A5,D0.w),D2 ;Start with the 4th character of the filename
cmpi.b #'9',D2 ;Test to see if it is a number
bgt yap050 ;Exit loop if not
cmpi.b #'0',D2
blt yap050
beq yap020
moveq #-1,D5
bra yap030
yap020: tst.w D5
beq yap040 ;Do not process preceeding zero's
yap030: move.b D2,(A4)+ ;Save number in buffer to print out later
subi.w #$30,D2
mulu #10,D3
add.w D2,D3 ;D3 will contain the actual amount of memory
yap040: addq.w #1,D0 ; needed for the buffer in "K" units
dbra D1,yap010
yap050: cmpi.w #0,D3
bne yap070
PRINTLINE error2 ;No size of buffer in Program Name
yap060 moveq #32,D3 ;Use default Printer Buffer size of
move.w #$3332,(A4)+ ; 32K
yap070: move.b #0,(A4)+
yap080: move.l D3,D5
moveq #10,D0
lsl.l D0,D5
add.l D6,D5
cmp.l D5,D7 ;Check to see if we have enough memory for
bgt yap090 ; requested PRINTER Spooler
PRINTLINE error3
PRINTLINE buflen ;No, then abort set up
PRINTLINE error4
bsr wte
TERM
yap090: KBSHIFT #-1 ;Finally, check to see if user wants to
andi.w #$6F,D0 ; abort installation by holding down
beq yap100 ; either shift key, or control key,
PRINTLINE error6 ; or alt key!
bsr wte
TERM
yap100: PRINTLINE mess01 ;Announce size of Printer Spooler set up
PRINTLINE buflen
PRINTLINE mess02
bsr wte
moveq #10,D0 ;Calculate total amount of printer buffer
lsl.l D0,D3 ; available to use
move.l #ypsend,D0 ;Add in addition program space that will only
sub.l #ypstrm,D0 ; be used once!
add.l D0,D3
move.l D3,length ;Save length of Printer Spooler needed
SETEXEC -1,#timerC/4 ;Set up link to timer C by
move.l D0,timret+2 ; chaining to old timer
SETEXEC timer,#timerC/4
SETEXEC newtrp,#trap13/4;Set up link to Trap #13
move.l D0,trpsve
clr -(sp) ;Save needed buffer size
move.l D5,-(sp) ;and return
move #keep,-(sp)
trap #gemdos
TERM
wte: moveq #10,D1 ;Routine to wait a bit to see messages
wte10: moveq #-1,D0
wte20: dbra D0,wte20
dbra D1,wte10
rts
go_sup: clr.l -(sp) ;Routine to enter SUPER mode, leaving return
go_s10: move.w #$20,-(sp) ; user stack pointer in D0
trap #gemdos
addq.l #6,sp
rts
go_use: move.l D0,-(sp) ;Routine to return to USER mode
bra go_s10
;
; Data Segment - volatile
;
attrib: dc.w 0
autobf: dc.b '\AUTO\',0
fname: dc.b 'YAPS*.PRG',0
tline: dc.b 13,10,'"YET ANOTHER PRINTER SPOOLER"',13,10
dc.b ' (timer C version)',13,10
dc.b ' written by Phillip R. Poulos',13,10,10,0
error1: dc.b 7,'** Original Program Name Not Found **',13,10,10,0
error2: dc.b 7,'** Size For Printer Spooler **',13,10
dc.b '** Not Found In Program Name **',13,10,10,0
error3: dc.b 7,'** Not Enough MEMORY Available **',13,10
dc.b '**To Set Up A ',0
error4: dc.b 'K Printer Spooler **',13,10
dc.b '** Installation Aborted! **',13,10,0
error5: dc.b 7,'** YAPS is already running... **',13,10
dc.b '** Installation Aborted! **',13,10,10
dc.b 'Clear the printer spooler (Y or N)? ',0
error6: dc.b 7,'** So you wish to abort installation! **',13,10
dc.b '** See if I do you any favors soon... **',13,10,0
mess01: dc.b 'Setting up a ',0
mess02: dc.b 'K Printer Spooler!',13,10,0
align.w
;
; BSS Segment - volatile
;
buflen: ds.b 10
drvbuf: ds.b 64
ypsend: end